﻿#include "pch.h"
#include "ICS.h"
#include "afxdialogex.h"
#include "CCoreOpsDlg.h"
#include "ICSDlg.h" // 包含父窗口头文件


// CCoreOpsDlg 对话框

IMPLEMENT_DYNAMIC(CCoreOpsDlg, CDialogEx)

CCoreOpsDlg::CCoreOpsDlg(CRfidReader* pReader, int& operatorRole, CWnd* pParent /*=nullptr*/) // 修改
	: CDialogEx(IDD_TAB_CORE_OPS, pParent)
	, m_pReader(pReader)
	, m_nOperatorRole(operatorRole) // 修改
	, m_commno(_T("5"))      // 设置一个默认串口号
	, m_sFirstBlock(_T("0"))
	, m_sBlockCount(_T("28"))
	, m_sBlockWrite(_T(""))
	, m_sDataWrite(_T(""))
{
}

BOOL CCoreOpsDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 初始化List Control
	m_listDataDisplay.InsertColumn(0, _T("块"), LVCFMT_LEFT, 40);
	m_listDataDisplay.InsertColumn(1, _T("十六进制数据"), LVCFMT_LEFT, 120);
	m_listDataDisplay.InsertColumn(2, _T("ASCII"), LVCFMT_LEFT, 80);
	m_listDataDisplay.SetExtendedStyle(m_listDataDisplay.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);

	UpdateConnectionState();
	return TRUE;
}


CCoreOpsDlg::~CCoreOpsDlg()
{
}

void CCoreOpsDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_EDIT_COMMNO, m_commno);
	DDX_Control(pDX, IDC_COMBO_UID_LIST, m_comboUidList);
	DDX_Text(pDX, IDC_EDIT_FIRST_BLOCK, m_sFirstBlock);
	DDX_Text(pDX, IDC_EDIT_BLOCK_COUNT, m_sBlockCount);
	DDX_Control(pDX, IDC_LIST_DATA_DISPLAY, m_listDataDisplay);
	DDX_Text(pDX, IDC_EDIT_BLOCK_WRITE, m_sBlockWrite);
	DDX_Text(pDX, IDC_EDIT_DATA_WRITE, m_sDataWrite);
}


BEGIN_MESSAGE_MAP(CCoreOpsDlg, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON_CONNECT, &CCoreOpsDlg::OnClickedButtonConnect)
	ON_BN_CLICKED(IDC_BUTTON_INVENTORY, &CCoreOpsDlg::OnClickedButtonInventory)
	ON_BN_CLICKED(IDC_BUTTON_READ, &CCoreOpsDlg::OnClickedButtonRead)
	ON_CBN_SELCHANGE(IDC_COMBO_UID_LIST, &CCoreOpsDlg::OnCbnSelchangeComboUidList)
	ON_BN_CLICKED(IDC_BUTTON_WRITE, &CCoreOpsDlg::OnClickedButtonWrite)
	ON_BN_CLICKED(IDC_BUTTON_FORMAT_CARD, &CCoreOpsDlg::OnBnClickedButtonFormatCard)
END_MESSAGE_MAP()


void CCoreOpsDlg::UpdateConnectionState()
{
	bool isConnected = m_pReader && m_pReader->IsConnected();

	GetDlgItem(IDC_BUTTON_CONNECT)->SetWindowText(isConnected ? _T("断开") : _T("连接"));
	GetDlgItem(IDC_EDIT_COMMNO)->EnableWindow(!isConnected);
	GetDlgItem(IDC_BUTTON_INVENTORY)->EnableWindow(isConnected);
	GetDlgItem(IDC_BUTTON_READ)->EnableWindow(isConnected);
	GetDlgItem(IDC_COMBO_UID_LIST)->EnableWindow(isConnected);
	GetDlgItem(IDC_BUTTON_WRITE)->EnableWindow(isConnected);
	GetDlgItem(IDC_BUTTON_FORMAT_CARD)->EnableWindow(isConnected);
	SetDlgItemText(IDC_STATIC_STATUS,( isConnected ? _T("状态: 已连接") : _T("状态: 未连接")));

	// 通知父窗口检查状态
	CICSDlg* pParent = (CICSDlg*)GetParent()->GetParent();
	if (pParent)
	{
		pParent->CheckAndUnlockTabs();
	}


}

// CCoreOpsDlg 消息处理程序
void CCoreOpsDlg::OnClickedButtonConnect()
{
	UpdateData(TRUE);

	if (!m_pReader->IsConnected())
	{
		if (m_commno.IsEmpty())
		{
			MessageBox(_T("请输入串口号。"), _T("错误"), MB_ICONERROR);
			return;
		}

		CWaitCursor wait;
		int iPort = _ttoi(m_commno);
		RfidResult result = m_pReader->Connect(iPort);

		if (result == RfidResult::Success)
		{
			MessageBox(_T("连接成功！"), _T("成功"), MB_ICONINFORMATION);
		}
		else if (result == RfidResult::PortOpenFailed)
		{
			MessageBox(_T("打开串口失败。请检查串口号或硬件连接。"), _T("连接失败"), MB_ICONERROR);
		}
		else
		{
			MessageBox(_T("设置读卡器协议失败。"), _T("错误"), MB_ICONERROR);
		}
	}
	else
	{
		m_pReader->Disconnect();
	}
	UpdateConnectionState();
}

void CCoreOpsDlg::OnClickedButtonInventory()
{
	m_comboUidList.ResetContent();
	CWaitCursor wait;

	std::vector<CString> uids;
	if (m_pReader->Inventory(uids) == RfidResult::Success && !uids.empty())
	{
		for (const auto& uid : uids)
		{
			m_comboUidList.AddString(uid);
		}
		m_comboUidList.SetCurSel(0);
	}
	else
	{
		MessageBox(_T("未找到卡片。"), _T("提示"), MB_ICONINFORMATION);
	}
}


void CCoreOpsDlg::OnCbnSelchangeComboUidList()
{
	// 可选：选中卡片后自动读取
}


void CCoreOpsDlg::OnClickedButtonRead()
{
	UpdateData(TRUE);
	m_listDataDisplay.DeleteAllItems(); // 清空列表

	int selIndex = m_comboUidList.GetCurSel();
	if (selIndex == CB_ERR)
	{
		MessageBox(_T("请先寻卡并选择一张卡。"), _T("提示"), MB_ICONINFORMATION);
		return;
	}
	if (m_sFirstBlock.IsEmpty())
	{
		MessageBox(_T("请输入起始块号。"), _T("错误"), MB_ICONERROR);
		return;
	}

	CWaitCursor wait;
	CString selectedUid;
	m_comboUidList.GetLBText(selIndex, selectedUid);

	int firstBlock = _ttoi(m_sFirstBlock);
	int blockCount = m_sBlockCount.IsEmpty() ? 1 : _ttoi(m_sBlockCount);
	if (blockCount <= 0) blockCount = 1;

	std::vector<BYTE> readData;
	RfidResult result = m_pReader->ReadMultipleBlocks(selectedUid, firstBlock, blockCount, readData);

	if (result == RfidResult::Success)
	{
		// 成功读取，将数据填充到List Control
		for (int i = 0; i < blockCount; ++i)
		{
			// 检查是否有足够的数据用于当前块
			if ((i * 4 + 4) > readData.size()) break;

			CString sBlockNum, sHexData, sAscii;
			sBlockNum.Format(_T("%02d"), firstBlock + i);

			// 格式化Hex数据
			sHexData.Format(_T("%02X %02X %02X %02X"),
				readData[i * 4 + 0],
				readData[i * 4 + 1],
				readData[i * 4 + 2],
				readData[i * 4 + 3]);

			// 格式化ASCII数据 (只转换可打印字符)
			for (int j = 0; j < 4; ++j)
			{
				BYTE ch = readData[i * 4 + j];
				sAscii += (isprint(ch) ? (char)ch : '.');
			}

			int nItem = m_listDataDisplay.InsertItem(i, sBlockNum);
			m_listDataDisplay.SetItemText(nItem, 1, sHexData);
			m_listDataDisplay.SetItemText(nItem, 2, sAscii);
		}
	}
	else
	{
		MessageBox(_T("读取卡片数据失败！"), _T("错误"), MB_ICONERROR);
	}
}

void CCoreOpsDlg::OnClickedButtonWrite()
{
	UpdateData(TRUE);

	// 数据校验
	int selIndex = m_comboUidList.GetCurSel();
	if (selIndex == CB_ERR)
	{
		MessageBox(_T("请先选择一张卡。"), _T("提示"), MB_ICONINFORMATION);
		return;
	}
	if (m_sBlockWrite.IsEmpty())
	{
		MessageBox(_T("请输入要写入的块号。"), _T("错误"), MB_ICONERROR);
		return;
	}
	if (m_sDataWrite.GetLength() != 8)
	{
		MessageBox(_T("请输入8个十六进制字符作为写入数据。"), _T("错误"), MB_ICONERROR);
		return;
	}

	CWaitCursor wait;
	CString selectedUid;
	m_comboUidList.GetLBText(selIndex, selectedUid);
	int blockNum = _ttoi(m_sBlockWrite);

	// 将十六进制字符串转换为BYTE数组
	BYTE dataToWrite[4] = { 0 };
	for (int i = 0; i < 4; ++i)
	{
		CString byteStr = m_sDataWrite.Mid(i * 2, 2);
		dataToWrite[i] = (BYTE)wcstol(byteStr, NULL, 16);
	}

	// 调用Reader类的方法执行写操作
	RfidResult result = m_pReader->WriteSingleBlock(selectedUid, blockNum, dataToWrite);

	// 根据结果显示提示
	if (result == RfidResult::Success)
	{
		MessageBox(_T("写入成功！"), _T("成功"), MB_ICONINFORMATION);
		// 写入成功后，可以自动触发一次读取来刷新显示
		OnClickedButtonRead();
	}
	else
	{
		MessageBox(_T("写入失败！"), _T("错误"), MB_ICONERROR);
	}
}

void CCoreOpsDlg::OnBnClickedButtonFormatCard()
{
	int selIndex = m_comboUidList.GetCurSel();
	if (selIndex == CB_ERR)
	{
		MessageBox(_T("请先寻卡并选择一张卡。"), _T("提示"), MB_ICONINFORMATION);
		return;
	}

	if (MessageBox(_T("警告：此操作将清空卡上所有数据，且不可恢复！\n确定要格式化选中的卡片吗？"), _T("确认格式化"), MB_YESNO | MB_ICONWARNING) != IDYES)
	{
		return;
	}

	CWaitCursor wait;
	CString selectedUid;
	m_comboUidList.GetLBText(selIndex, selectedUid);

	BYTE zeroBlock[4] = { 0 };
	bool bSuccess = true;
	for (int i = 0; i < CARD_BLOCK_COUNT; ++i)
	{
		if (m_pReader->WriteSingleBlock(selectedUid, i, zeroBlock) != RfidResult::Success)
		{
			bSuccess = false;
			MessageBox(_T("格式化失败！"), _T("错误"), MB_ICONERROR);
			break;
		}
	}


	if (bSuccess)
	{
		MessageBox(_T("卡片格式化成功！"), _T("成功"), MB_ICONINFORMATION);
		OnClickedButtonRead();
	}
}